home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Night Owl 6
/
Night Owl's Shareware - PDSI-006 - Night Owl Corp (1990).iso
/
016a
/
love4th.zip
/
REDEFINE.DOC
< prev
next >
Wrap
Text File
|
1991-10-01
|
7KB
|
205 lines
Redefining and Revectoring Forth Definitions
============================================
Concept
-------
In constructing Forth application programmes, words are defined by
using previously defined words as building blocks. This bottom-up
process precludes the use of forward referencing or mutual recursion
but is normally sufficient to build quite complex software.
There are many occasions though, when the ability to reference a word
before it has been defined or, for example, when the action of a low
level word needs to be changed dynamically (ie. during program
execution), that a portable and convenient method to do this becomes
necessary.
Definition of Terms
-------------------
Redefine: A word is redefined when its action is changed after its
definition has been compiled. Redefinition can occur
dynamically at run-time but is generally used to
permanently change the the action of a word.
Revector: Revectoring a word refers to the changing of the action
of a Forth word at run-time. This is the prefered method
for changing a word's action many times at run-time.
Vector: A vector is the information necessary to execute a word
as if it had been compiled into a definition or typed on
the command line. The vector information is system
specific but should be hidden from the programmer so
that code which uses redefinitions, or allows run-time
revectoring, can be ported to other systems or computer
architectures. The vector is kept in a location called a
vector field, known to the dynamic word.
Reasons for Redefining and Revectoring
--------------------------------------
(1) To change the action of a low level word that is the foundation
for many other higher level words when it is inconvenient to
recompile the entire system.
(2) To allow mutual recursion or forward referencing. This is
accomplished by first defining a dummy word and then later
redefining it to perform its correct action.
(3) To dynamically redirect input or output within an application
while allowing higher level words to be device independant.
(4) To develop and test an application interactively and then change
the action of hardware specific words before committing the code
to EPROM.
(5) To chain abort handlers or other error handlers together to
accomplish application specific actions on run-time execution
errors.
Word List
---------
REDEFINE ( -- )
Used in the form:
Redefine <word1> <word2>
and can be read as "redefine <word1> do the same thing as
<word2>".
RESTORE ( -- )
Used in the form:
RESTORE <word>
where <word> has been previously redefined, RESTORE will restore
the original function of <word>.
MAKE_DYNAMIC ( -- )
Used in the form:
MAKE_DYNAMIC <word>
to make <word> dynamically revectorable.
This allots space in the dictionary for a vector field, extracts the
vector from <word>, stores the vector into the vector field and
alters the code field address of <word> so that when <word>
executes it finds the vector in its vector field and executes it.
REVECTOR ( -- )
An immediate word used in the form:
REVECTOR <word1> <word2>
where <word1> is a dynamically revectorable word. <word2> is any
other Forth word. Revector changes the vector field at <word1> by
storing the vector extracted from <word2>.
VECTOR_FROM ( -- )(compiling)
( -- cfa, contents_of_cfa )(executing)
An immediate word used in the form:
VECTOR_FROM <word>
From the next word in the input stream extract the cfa and the
contents of the cfa . If the state is compiling, then the vector
is compiled as a dliteral. This word operates on any Forth word.
EXECUTE_VECTOR ( cfa, contents_of_cfa -- )
Executes the word specified by the two-part vector on the
stack.
GETVECTOR ( -- )( compiling )
( -- cfa, cfa_contents )( executing )
An immediate word used in the form:
GETVECTOR <word>
where <word> is a dynamically revectorable word. If the state
is compiling then GETVECTOR compiles the cfa of <word> as a
literal followed by <GETVECTOR>. This word is used to
retrieve the vector from the vector field of <word>, to be
stored in a variable, passed to EXECUTE_VECTOR or operated on
later with SETVECTOR.
SETVECTOR ( cfa1, cfa1_contents -- )(executing)
( -- )(compiling)
An immediate word used in the form:
SETVECTOR <word>
where <word> is a dynamically revectorable word. When
compiling, SETVECTOR compiles the cfa of <word> as a literal
followed by <SETVECTOR>. This word is used to store the
vector that is on the stack at run-time into the vector field
of <word>.
Examples
--------
Forward Referencing:
: second_word ; ( make a dummy )
( a word which executes another word that is define later )
: first_word ( -- )
second_word ;
( the second word executes the previously defined word)
: <second_word> ( -- )
first_word ;
( now complete the circle by making second_word execute )
( something useful )
redefine second_word <second_word>
Input and Output Redirection:
make_dynamic emit ( make emit dynamically revectorable )
( output a character in textmode to the LCD Display )
: LCD_text_EMIT ( c -- )
dup bl <
if
case
7 of beep endof
8 of do_backspace endof
9 of do_tab endof
10 of do_linefeed endof
13 of do_return endof
endcase
else
LCDwrite lcd! ( write the char )
1 #out +!
1 cursor_addr +!
#out @ chars/line = ( is cursor past last column? )
if do_return
do_linefeed
then
then
;
\ Later ...
: app_word ( n1 n2 -- )
...
revector emit LCD_text_EMIT
... ;
Chaining error handlers and abort handlers:
( a new abort that executes the old abort afterwards )
: <locals_abort> ( -- )
LP! ( initialize the local stack )
<cleanup_locals> ( restore all pointers and flags )
vector_from abort execute_vector ; ( execute previous abort)
( chain the special abort handler before abort )
redefine abort <locals_abort>